// Reflect 出现的意义
// Reflect 静态方法 与 Proxy 的拦截方法 一一对应
// Reflect 的目的是 Object 是语言内部的方法，尽量少往 Object 上面放。
// 出错后 Reflect 返回 false 而不是报错
// 让 Object 操作 编程函数行为 而不是命令式

// 静态方法
Reflect.apply()
Reflect.construct()
Reflect.defineProperty()
Reflect.deleteProperty()
Reflect.has()
Reflect.preventExtensions()
Reflect.isExtensible()
Reflect.getPrototypeOf()
Reflect.setPrototypeOf()
Reflect.ownKeys()
Reflect.getOwnPropertyDescriptor()
Reflect.set()
Reflect.get()

// 使用 Proxy 实现 观察者模式
let queuedObservers = new Set()

const observe = (fn) => queuedObservers.add(fn)
const observerable = (obj) => new Proxy(obj, { set })

function set(target, key, value, receiver) {
  const result = Reflect.set(target, key, value, receiver)
  queuedObservers.forEach((observe) => observe())
  return result
}

const person = observerable({
  name: 'zhangsan',
  age: 20,
})
function print() {
  console.log(`${person.name}, ${person.age}`)
}
observe(print)
person.name = 'lisi'
